from audio_pkg.core.services.api_client import CreateAudioTask, QueryTask
from audio_pkg.core.handler.status_handler import TaskFileHandler, TaskRunningHandler, TaskSuccessHandler, TaskFailureHandler, TaskParseHandler
from audio_pkg.core.services.audiosave import AudioSaver
from audio_pkg.core.printer.task_printer import QueryTaskPrinter
from audio_pkg.core.printer.print_judge import QueryPrintQuery,QueryPrintAuto
from audio_pkg.models.taskdata import TaskSuccessDate,TaskRunningDate,TaskFailureDate
from audio_pkg.utils.get_token import GetAccessToken
from termcolor import colored 
from pathlib import Path
from time import sleep
import sys

#任务创建器
class TaskCreator:
    def __init__(self,task_data_dir:Path,api_url, args, logger, getaccesstoken:GetAccessToken):
        '''
        arg:命令行参数
        logger:日志
        getaccesstoken:GetAccessToken类
        '''
        self.task_data_dir = task_data_dir.resolve()
     
        self.api_url = api_url
        self.args = args
        self.getaccesstoken = getaccesstoken
        self.logger = logger
        
    def create_audio_task(self):
        file_handle = TaskFileHandler(self.logger,self.task_data_dir)
        return CreateAudioTask(
            api_url = self.api_url,
            logger = self.logger,
            gettoken = self.getaccesstoken,
            file_handler = file_handle,
            text = self.args.text,
            speed = self.args.speed,
            volume = self.args.volume,
            voice = self.args.chcr,
            pitch = self.args.pitch,
            format = self.args.format,
            enable_subtitle = self.args.enable_subtitle
        )
    
    #开始创建
    def create_task(self):
        create_task = self.create_audio_task()
        create_task.create_task()
        return create_task.back_task_info()



# 4. 查询任务
class TaskQuery:
    def __init__(self,api_url,getaccesstoken,logger):
        """
        初始化 TaskQuery 类。

        :param getaccesstoken: GetAccessToken 类的实例，用于获取访问令牌。
        :param logger: 日志记录器，用于记录日志。
        """
        self.api_url = api_url
        self.query_task = QueryTask(self.api_url,logger,getaccesstoken)
        self._valid_task_list = None
        self.invalid_task_list = None

        self.printer = QueryTaskPrinter(logger)
    
    def query(self, task_id=None):

        self.query_task.query_task(task_id)
        self.invalid_task_list, self._valid_task_list = self.query_task.result()

    #打印数据
    def print_query(self):
        """打印查询结果（手动模式）。"""
        printdata = QueryPrintQuery(self.printer,self._valid_task_list,self.invalid_task_list)
        printdata.print_data()

        """打印查询结果（自动模式）。"""
    def print_auto(self):
        printdata=QueryPrintAuto(self.printer,self._valid_task_list,self.invalid_task_list)
        printdata.print_data()

    def exit_judgu(self):
        """判断是否需要退出程序。"""
        if not self._valid_task_list:
            sys.exit(0)

    #返回有效数据
    @property
    def back_data(self):
        """
        返回有效数据。

        :return: 有效任务列表，如果为空则返回 None。
        """
        return self._valid_task_list
        

    

# 5. 任务解析
class TaskParser:
    def __init__(self,mime_map:dict):
        self.mime_map = mime_map
        self._task_data_list = None

    def parse(self, valid_task_list):
        handlers = {
            "Success": TaskSuccessHandler(self.mime_map),
            "Running": TaskRunningHandler(),
            "Failure": TaskFailureHandler()
        }
        task_parse = TaskParseHandler(handlers)
        task_parse.handle(valid_task_list)
        self._task_data_list = task_parse.result()
        

    @property
    def task_data(self):
        return self._task_data_list


# 6. 任务保存
class TaskFilterSaver:
    def __init__(self, task_data_list, logger,audio_save:AudioSaver):
    
        self.logger = logger
        self.task_data_list = task_data_list
        self.audio_save = audio_save
        self.data_list = []
        self._data_path = []
        self.filter_handler()

    def save(self):

        self._data_path = self.audio_save.save_all_audios(self.data_list)

        
    def handle_success(self, task):
        self.data_list.append(task)

    def handle_running(self, task):
        self.logger.info(f"任务 {task.task_id} 正在处理中，状态: {task.status}")

    def handle_failure(self, task):
        self.logger.error(f"任务 {task.task_id} 失败，错误信息: {task.error_message}")

    def handle_unknown(self, task):
        self.logger.warning(f"未知任务类型: {type(task)}")

    def filter_handler(self):
        # 使用字典映射任务类型到对应的处理方法
        handler_map = {
            TaskSuccessDate: self.handle_success,
            TaskRunningDate: self.handle_running,
            TaskFailureDate: self.handle_failure
        }

        # 遍历任务列表并调用对应的处理方法
        for task in self.task_data_list:
            handler = handler_map.get(type(task), self.handle_unknown)  # 默认调用 handle_unknown
            handler(task)

    def result(self):
        return self._data_path


class TaskAutoSave:
    # 类常量：默认延迟时间和最大尝试次数
    DEFAULT_DELAY = 4
    DEFAULT_TIMES = 15

    def __init__(
            self, api_url:str,
            config_path:Path,
            mime_map:dict,
            token:GetAccessToken,
            logger, 
            task_id: str, 
            delay: int = DEFAULT_DELAY, 
            times: int = DEFAULT_TIMES
    ):
        """
        初始化 TaskAutoSave 类。

        :param logger: 日志记录器
        :param task_id: 任务 ID
        :param delay: 每次查询的延迟时间（秒），默认为 4
        :param times: 最大查询次数，默认为 15
        """
        self.api_url = api_url
        self.config_path = config_path
        self.token = token
        self.mime_map = mime_map
        self.logger = logger
        self.taskid = task_id
        self.delay = delay
        self.times = times
        self.query = QueryTask(self.api_url,self.logger, self.token)  # 初始化任务查询器
        self.taskparse = TaskParser(self.mime_map)  # 初始化任务解析器
        self.audio_save = AudioSaver(self.logger,self.config_path)
        self.invalid_data = None  # 无效数据
        self.valid_data = None  # 有效数据

    def start_query(self, times: int) -> bool:
        """
        执行一次任务查询，并保存有效数据。

        :param times: 当前查询次数
        :return: 如果任务已保存，返回 True；否则返回 False
        """
        try:
            # 查询任务
            self.query.query_task(self.taskid)
            self.invalid_data, self.valid_data = self.query.result()

            # 解析有效数据
            self.taskparse.parse(self.valid_data)

            # 过滤并保存任务数据
            self.TaskFilter = TaskFilterSaver(self.taskparse.task_data, self.logger,self.audio_save)
            self.TaskFilter.save()

            # 检查任务是否已保存
            if self.TaskFilter.result():
                self.logger.info(colored("任务已经保存", "green"))
                return True
            else:
                self.logger.info(colored(f"第 {times + 1} 次请求中......", "yellow"))
                sleep(self.delay)
                return False
        except Exception as e:
            self.logger.error(colored(f"任务查询失败: {e}", "red"))
            raise

    def for_try(self):
        """
        循环执行任务查询，直到任务保存或达到最大尝试次数。
        """
        for i in range(self.times):
            if self.start_query(i):
                return  # 任务已保存，退出循环
        self.logger.warning(colored(f"已达到最大尝试次数 {self.times}，任务未保存", "red"))
        

